package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.huanxin.HuanXinTemplate;
import com.itheima.domain.db.Question;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Friend;
import com.itheima.domain.mongo.RecommendUser;
import com.itheima.domain.mongo.Sound;
import com.itheima.domain.mongo.Visitor;
import com.itheima.domain.vo.*;
import com.itheima.service.db.QuestionService;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.*;
import com.itheima.util.ConstantUtil;
import com.itheima.util.TimeUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;

@Component
public class MakeFriendManager {

    @Reference
    private RecommendUserService recommendUserService;
    @Reference
    private UserInfoService userInfoService;

    /**
     * 查询今日佳人
     *
     * @return 页面显示数据对象
     */
    public RecommendUserVo todayBest() {
        //获取当前登录用户id
        Long loginUserId = UserHolder.getId();
        //根据用户id查询缘分值最高的用户
        RecommendUser recommendUser = recommendUserService.findRecommendUser(loginUserId);
        //查询推荐用户的个人信息
        UserInfo userInfo = userInfoService.findById(recommendUser.getUserId());
        //构建前端返回对象
        RecommendUserVo recommendUserVo = new RecommendUserVo();
        recommendUserVo.setUserInfo(userInfo);
        recommendUserVo.setFateValue(recommendUser.getScore().longValue());
        return recommendUserVo;
    }

    /**
     * 查询推荐好友列表
     *
     * @param page     页码
     * @param pageSize 每页条数
     * @return 页面封装对象
     */
    public PageBeanVo recommendFriend(Integer page, Integer pageSize) {
        //获取当前登录用户id
        Long loginUserId = UserHolder.getId();
        //查询推荐给当前用户的用户
        PageBeanVo pageBeanVo = recommendUserService.findRecommendUserList(loginUserId, page, pageSize);
        List<RecommendUser> items = (List<RecommendUser>) pageBeanVo.getItems();
        //构建前端返回对象集合
        List<RecommendUserVo> recommendUserVoList = new ArrayList<>();
        //查询推荐用户的个人信息
        for (RecommendUser recommendUser : items) {
            RecommendUserVo recommendUserVo = new RecommendUserVo();
            UserInfo userInfo = userInfoService.findById(recommendUser.getUserId());
            recommendUserVo.setUserInfo(userInfo);
            recommendUserVo.setFateValue(recommendUser.getScore().longValue());
            recommendUserVoList.add(recommendUserVo);
        }
        pageBeanVo.setItems(recommendUserVoList);
        return pageBeanVo;
    }

    /**
     * 查询佳人详细信息
     *
     * @param recommendId 今日佳人id
     * @return 佳人详细信息对象
     */
    public RecommendUserVo bestUserInfo(Long recommendId) {
        //获取当前登录用户id
        Long loginUserId = UserHolder.getId();
        //查询登录用户与佳人的缘分值
        RecommendUser recommendUser = recommendUserService.findFateValue(loginUserId, recommendId);
        //查询推荐用户的个人信息
        UserInfo userInfo = userInfoService.findById(recommendId);
        RecommendUserVo recommendUserVo = new RecommendUserVo();
        recommendUserVo.setUserInfo(userInfo);
        recommendUserVo.setFateValue(recommendUser.getScore().longValue());
        //向visitor表中添加访问记录
        visitorService.saveVisitor(loginUserId, recommendId, ConstantUtil.VISITOR_SOURCE_INDEX);
        return recommendUserVo;
    }

    @Reference
    private QuestionService questionService;

    /**
     * 查看陌生人问题
     *
     * @param userId 用户id
     * @return 陌生人问题
     */
    public String strangerQuestion(Long userId) {
        //根据用户id查询陌生人问题
        Question question = questionService.findByUserId(userId);
        if (question == null) {
            return "你是猪吗?";
        }
        return question.getStrangerQuestion();
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Reference
    private VisitorService visitorService;

    /**
     * 查看历史访客
     *
     * @return 访客集合
     */
    public List<VisitorVo> findVisitorVoList() {
        //获取登录用户的id
        Long userId = UserHolder.getId();
        //从redis中读取上次登录时间
        String lastTime = stringRedisTemplate.opsForValue().get(ConstantUtil.LAST_ACCESS_TIME + userId);
        //如果没有上次登录时间,标识是第一次登录,则返回空
        if (StrUtil.isEmpty(lastTime)) {
            //向redis中存入登陆时间
            stringRedisTemplate.opsForValue().set(ConstantUtil.LAST_ACCESS_TIME + userId, String.valueOf(System.currentTimeMillis()));
            return null;
        }
        //查询历史访客
        List<Visitor> visitorList = visitorService.findVisitorList(userId, lastTime);
        //创建返回对象集合
        List<VisitorVo> voList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(visitorList)) {
            for (Visitor visitor : visitorList) {
                VisitorVo visitorVo = new VisitorVo();
                //查询访客个人信息
                UserInfo userInfo = userInfoService.findById(visitor.getVisitorUserId());
                visitorVo.setUserInfo(userInfo);
                //查询和访客之间的缘分值
                RecommendUser recommendUser = recommendUserService.findFateValue(userId, visitor.getVisitorUserId());
                visitorVo.setFateValue(recommendUser.getScore().longValue());
                voList.add(visitorVo);
            }
        }
        return voList;
    }

    @Reference
    private UserLocationService userLocationService;

    /**
     * 保存位置信息
     *
     * @param latitude  纬度
     * @param longitude 经度
     * @param addrStr   地址描述
     */
    public void saveOrUpdateUserLocation(Double latitude, Double longitude, String addrStr) {
        //获取当前用户id
        Long userId = UserHolder.getId();
        //上传位置信息
        userLocationService.saveOrUpdateUserLocation(latitude, longitude, addrStr, userId);
    }

    /**
     * 查询附近的人
     *
     * @param gender   性别
     * @param distance 距离(m)
     * @return 附近的人集合
     */
    public List<NearUserVo> findNearbyUser(String gender, Integer distance) {
        //获取当前登录用户id
        Long userId = UserHolder.getId();
        List<Long> nearbyUserList = userLocationService.findNearbyUser(gender, distance, userId);
        //构建返回对象
        List<NearUserVo> nearUserVos = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(nearbyUserList)) {
            for (Long id : nearbyUserList) {
                NearUserVo nearUserVo = new NearUserVo();
                UserInfo userInfo = userInfoService.findById(id);
                //排除自己
                if (id == userId) {
                    continue;
                }
                //排除和前台勾选性别不一致的用户
                if (!StrUtil.equals(gender, userInfo.getGender())) {
                    continue;
                }
                BeanUtil.copyProperties(userInfo, nearUserVo);
                nearUserVos.add(nearUserVo);
            }
        }
        //System.out.println("附近的人:"+nearUserVos);
        return nearUserVos;
    }

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    /**
     * 回复陌生人问题
     *
     * @param userId 发给谁
     * @param reply  回答
     */
    public void replyStrangerQuestion(String userId, String reply) {
        //获取当前登录用户
        Long loginUserId = UserHolder.getId();
        //查询登录用户个人信息
        UserInfo userInfo = userInfoService.findById(loginUserId);
        //查询回答的陌生人问题
        Question question = questionService.findByUserId(Long.valueOf(userId));
        //构建回答数据
        Map map = new HashMap<>();
        map.put("userId", loginUserId.toString()); //当前登录用户id
        map.put("nickname", userInfo.getNickname()); //当前用户昵称
        if (question == null) {
            map.put("strangerQuestion", "远赴人间惊鸿宴");//问题
        } else {
            map.put("strangerQuestion", question.getStrangerQuestion());//问题
        }
        map.put("reply", reply);//回答的内容
        //将map格式转为json
        String jsonString = JSON.toJSONString(map);
        //System.out.println(jsonString);
        //发送消息
        huanXinTemplate.sendMsg(userId, jsonString);
    }


    @Reference
    private FriendService friendService;

    /**
     * 添加联系人
     *
     * @param userId 聊天对象id
     */
    public void addContact(String userId) {
        Long loginUserId = UserHolder.getId();
        friendService.addContact(loginUserId, Long.valueOf(userId));
        //2.添加环信好友
        huanXinTemplate.addContacts(loginUserId, Long.valueOf(userId));
    }

    /**
     * 查看好友列表
     *
     * @param page     页码
     * @param pageSize 页面大小
     * @return 分页对象
     */
    public PageBeanVo findContactList(Integer page, Integer pageSize) {
        //获取登录用户id
        Long loginUserId = UserHolder.getId();
        //查询好友列表
        PageBeanVo pageBeanVo = friendService.findContactList(page, pageSize, loginUserId);
        //构建返回对象
        List<ContactVo> voList = new ArrayList<>();
        //获取朋友集合
        List<Friend> items = (List<Friend>) pageBeanVo.getItems();
        if (CollectionUtil.isNotEmpty(items)) {
            for (Friend item : items) {
                ContactVo contactVo = new ContactVo();
                UserInfo userInfo = userInfoService.findById(item.getFriendId());
                contactVo.setUserInfo(userInfo);
                contactVo.setUserId(item.getFriendId() + "");
                voList.add(contactVo);
            }

        }
        pageBeanVo.setItems(voList);
        return pageBeanVo;
    }

    /**
     * 查询探花卡片
     *
     * @param page     页码
     * @param pageSize 每页条数
     * @return 页面对象
     */
    public PageBeanVo findUserCard(Integer page, Integer pageSize) {
        //获取登录用户id
        Long loginUserId = UserHolder.getId();
        //查询推荐给当前用户集合
        PageBeanVo recommendUserList = recommendUserService.findRecommendUserList(loginUserId, page, pageSize);
        List<RecommendUser> items = (List<RecommendUser>) recommendUserList.getItems();
        List<RecommendUserVo> voList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(items)) {
            for (RecommendUser user : items) {
                RecommendUserVo userVo = new RecommendUserVo();
                UserInfo userInfo = userInfoService.findById(user.getUserId());
                userVo.setUserInfo(userInfo);
                voList.add(userVo);
            }
        }
        recommendUserList.setItems(voList);
        return recommendUserList;
    }

    @Reference
    private UserLikeService userLikeService;

    /**
     * 右滑喜欢用户
     *
     * @param likeUserId 喜欢用户id
     */
    public void saveUserLike(Long likeUserId) {
        //获取登录用户id
        Long loginUserId = UserHolder.getId();
        //保存用户喜欢信息
        userLikeService.saveUserLike(likeUserId, loginUserId);
        //查询我喜欢的用户是否也喜欢我
        boolean flag = userLikeService.likeEachOther(loginUserId, likeUserId);

        //如果为true,将两人关系保存进朋友表和环信里
        if (flag) {
            //将两人保存为朋友关系(friend表)
            friendService.addContact(loginUserId, likeUserId);
            //在环信中也添加为好友
            huanXinTemplate.addContacts(loginUserId, likeUserId);
        }
    }

    /**
     * 左滑不喜欢
     *
     * @param unLoveId 不喜欢用户id
     */
    public void unLoveUser(Long unLoveId) {
        //获取登录用户id
        Long loginUserId = UserHolder.getId();
        //查询是否相互喜欢
        boolean flag = userLikeService.likeEachOther(loginUserId, unLoveId);
        //如果相互喜欢,删除双方的好友关系
        if (flag) {
            friendService.deleteFriend(loginUserId, unLoveId);
            huanXinTemplate.deleteContacts(loginUserId, unLoveId);
        }
        //删除用户喜欢信息
        userLikeService.deleteUserLike(loginUserId, unLoveId);

    }

    @Autowired
    private FastFileStorageClient client;  //存储的客户端  注入会报错 , 不影响执行
    @Autowired
    private FdfsWebServer webServer; // tracker的服务器  注入会报错 , 不影响执行
    @Reference
    private SoundService soundService;

    /**
     * 桃花传音
     *
     * @param soundFile 语音
     */
    public void peachBlossom(MultipartFile soundFile) throws IOException {
        //获取登录用户id
        Long loginUserId = UserHolder.getId();
        //构建语音对象
        Sound sound = new Sound();
        sound.setUserId(loginUserId);
        //上传语音
        if (soundFile != null && soundFile.getSize() != 0) {
            //上传视频
            //参数一:文件的流对象
            //参数二:文件大小
            //参数三:文件后缀名
            //参数四:元数据,传空
            StorePath storePath = client.uploadFile(soundFile.getInputStream(), soundFile.getSize(),
                    FileUtil.extName(soundFile.getOriginalFilename()), null);
            //视频存储路径
            sound.setSoundUrl(webServer.getWebServerUrl() + storePath.getFullPath());
        }
        soundService.saveSound(sound);
    }

    /**
     * 接收语音
     *
     * @return
     */
    public SoundVo receiveSound() {
        //获取当前登录用户
        Long loginUserId = UserHolder.getId();
        //构建页面语音对象
        SoundVo soundVo = new SoundVo();
        //获取当前距离今晚的毫秒值
        long time = TimeUtil.calculate();
        System.out.println("毫秒值:" + time);
        //判断redis中是否有标志
        if (!stringRedisTemplate.hasKey(ConstantUtil.SOUND_COUNT + loginUserId)) {
            //没有该标志,为该用户注入默认次数
            stringRedisTemplate.opsForValue().set(ConstantUtil.SOUND_COUNT + loginUserId, ConstantUtil.SOUND_Number, Duration.ofSeconds(time));
            soundVo.setRemainingTimes(Integer.parseInt(ConstantUtil.SOUND_Number));
        }
        //剩余次数
        String count = stringRedisTemplate.opsForValue().get(ConstantUtil.SOUND_COUNT + loginUserId);
        //随机获取一个语音
        Sound sound = soundService.getRandomSound(loginUserId);
        if (sound != null) {
            UserInfo userInfo = userInfoService.findById(sound.getUserId());
            BeanUtil.copyProperties(userInfo, soundVo);
            soundVo.setSoundUrl(sound.getSoundUrl());
            soundVo.setRemainingTimes(Integer.parseInt(count) - 1);
            time = TimeUtil.calculate();
            stringRedisTemplate.opsForValue().set(ConstantUtil.SOUND_COUNT + loginUserId, soundVo.getRemainingTimes().toString(),Duration.ofSeconds(time));
            return soundVo;
        }
        //System.out.println(soundVo);
        return null;
    }
}
